package com.etrans.baf.analyse.task.track.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.mybatis.spring.SqlSessionTemplate;
import org.quartz.utils.DBConnectionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.etrans.baf.analyse.task.track.domain.Vehicle;
import com.etrans.baf.analyse.util.BaseService;
import com.etrans.baf.analyse.util.Constants;
import com.etrans.baf.analyse.util.DateUtils;
import com.etrans.baf.analyse.util.SpringWebContextUtil;
import com.etrans.baf.analyse.util.Sysconfig;
import com.etrans.baf.analyse.util.XmlReader;
import com.mongodb.BasicDBObject;
import com.mongodb.CommandResult;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MapReduceCommand;
import com.mongodb.MapReduceOutput;

@Service
public class TouristService extends BaseService{

	@Autowired
	private MongoTemplate egovMongoTemplate;
	
	public MongoTemplate getEgovMongoTemplate() {
		return egovMongoTemplate;
	}
	public TouristService() {
		super.masterAliases = "com.etrans.baf.analyse.task.track.persistence.trackMapper";
 	}
	@Override
	protected SqlSessionTemplate getMasterSessionTemplate() {
		return (SqlSessionTemplate) SpringWebContextUtil.getApplicationContext().getBean("dataSourceMasterSession");

	}
	/*
	 * 旅游车
	 */
	private List<Vehicle> getTouristVehicle(){
		return (List<Vehicle>) this.select("getTouristVehicle", null);
	}
	private List getImportPoint(){
		return (List<HashMap<String,Object>>) this.select("getImportPoint", null);
	}
	/**
	 * 旅游车分析
	 * @param analyse_date
	 * @throws Exception 
	 */
	public void touristInsert(String analyse_date) throws Exception{
		List<Vehicle> list = getTouristVehicle();
		HashMap<Integer,Vehicle> vMap = new HashMap();
		for (Vehicle v : list) {
			vMap.put(v.getId(), v);
		} 
		String dirUrl=System.getProperty("analyse")+Sysconfig.getPropValueByCode("track");

		Date analyseDate = DateUtils.parse(analyse_date, Constants.DATE_YYYY_MM_DD);
		String table_date =DateUtils.format(analyseDate, Constants.DATE_YYMMDD);
		touristAnalyse(dirUrl,analyseDate,table_date,vMap);
	}
	public void enterpriseAnalyse(String analyse_date) throws Exception{
		String dirUrl=System.getProperty("analyse")+Sysconfig.getPropValueByCode("track");
		Date analyseDate = DateUtils.parse(analyse_date, Constants.DATE_YYYY_MM_DD);
		String table_date =DateUtils.format(analyseDate, Constants.DATE_YYMMDD);
		touristEnterpriseAnalyse(dirUrl, analyseDate, table_date); 
	}
	
	public void areaInout(/*String analyse_date*/ String analyse_date_hour) throws Exception{
		List<HashMap<String,Object>> pointlist = getImportPoint();
        if(pointlist!=null && pointlist.size()>0){
        	Date curdate = new Date();
			String analyse_date = DateUtils.format(curdate, Constants.DATE_YYYY_MM_DD);
		
			Date analyseDate = DateUtils.parse(analyse_date, Constants.DATE_YYYY_MM_DD);
			
			String table_date =DateUtils.format(analyseDate, Constants.DATE_YYMMDD);
			
			String start_hour = DateUtils.getBeforeOne(analyse_date_hour);
			String start_time = start_hour+":00:00.000";
			String end_time = start_hour+":59:59.999";

			List<Vehicle> list = getTouristVehicle();
			HashMap<String,Vehicle> vMap = new HashMap();
			for (Vehicle v : list) {
				vMap.put(v.getVehicle_no(), v);
			} 
			StringBuffer sb = new StringBuffer();
		    DBObject all = new BasicDBObject();
			for (HashMap<String, Object> map : pointlist) {
				DBObject ob = new BasicDBObject();
				ob.put("range", map.get("radius"));
				List<Double> pl = new ArrayList<Double>();
				pl.add(Double.parseDouble(String.valueOf(map.get("lon"))));
				pl.add(Double.parseDouble(String.valueOf(map.get("lat"))));
				ob.put("point", pl);
				ob.put("area_name", map.get("name"));
				all.put(String.valueOf(map.get("id")),ob);
			}
			
			String dirUrl=System.getProperty("analyse")+Sysconfig.getPropValueByCode("track");
			
			areaInoutAnalyse(dirUrl, analyseDate, table_date, vMap,all,DateUtils.parse(start_time),DateUtils.parse(end_time));
        }
	}
	/**
	 * 重点区域出入
	 * @param dirUrl
	 * @param analyseDate
	 * @param table_date
	 * @param vMap
	 * @param all
	 *
	 */
	private void areaInoutAnalyse(String dirUrl,Date analyseDate,String table_date,HashMap<String,Vehicle> vMap,DBObject all,Date startTime,Date endTime){
		Map<String,String> map = XmlReader.readXmlToMapReduce(dirUrl+"tourist_vehicle_area_inout.xml");
        if(map!=null&& map.size()>0){
        	DBObject command = new BasicDBObject();
	       	DBObject sort = new BasicDBObject();
	       	sort.put("_id",1);
	    	DBCollection  db = egovMongoTemplate.getDb().getCollection("gps_info_"+table_date);
	    	DBObject query = null;
	    	if(startTime!=null && endTime!=null){
	    		query= new BasicDBObject();
	    		DBObject time = new BasicDBObject();
	    		time.put("$gte", startTime);
	    		time.put("$lte",endTime);
	    		query.put("gps_time",time);
	    	}
	    	 MapReduceCommand cmd = new MapReduceCommand(db,
	         map.get("map"), map.get("reduce"), "gps_track_geo_"+System.currentTimeMillis(), MapReduceCommand.OutputType.REPLACE, query);
	         String fin = map.get("finalize")/*.replaceAll("DATE_YYMMDD", table_date)*/;
	    	 cmd.setFinalize(fin);  
	         cmd.setSort(sort);
	         Map<String,Object> scope = new HashMap<String, Object>();
	         scope.put("_new_point_area", all);
	         cmd.setScope(scope);
	         MapReduceOutput out = db.mapReduce(cmd);  
	         DBCollection resultColl = out.getOutputCollection();
	         String o_name = resultColl.getName();
	         DBObject q1 = new BasicDBObject();
	         DBObject ex = new BasicDBObject();
	         ex.put("$exists", 1);
	         q1.put("value.0",ex);
	         DBCursor cursor= resultColl.find(q1);
	         List list =new ArrayList();
	         if (cursor!=null) {  
	        	     List<DBObject> lob = cursor.toArray();
	        	     for (DBObject ob : lob) { 
	        	    	 String[] _id = String.valueOf(ob.get("_id")).split(":");
	        	    	 if(vMap.get(_id[0])!=null){
	        	    		 Vehicle veh = vMap.get(_id[0]);
				        	 List<DBObject> value =   (List<DBObject>) ob.get("value"); 
	 		            	 for (DBObject dbv : value) {
	 		            		 Date enter = (Date) dbv.get("enter_time");
		 		            	dbv.put("_id",DateUtils.format(enter, Constants.DATE_YYMMDDHHMMSS)+":"+veh.getVehicle_no()+":"+veh.getVehicle_color()+":"+dbv.get("area_id"));
	 		            		dbv.put("vehicle_color", veh.getVehicle_color());
	 		            		dbv.put("vehicle_no",veh.getVehicle_no());
	 		            		dbv.put("enterprise_id", veh.getEnterprise_id());
	 		            		dbv.put("enterprise_name", veh.getEnterprise_name());
								dbv.removeField("coordinates");
								dbv.removeField("gps_time");
								dbv.put("analyse_date",(startTime!=null && endTime!=null)?startTime:analyseDate);/*analyseDate*/
								list.add(dbv);
							 }
	        	    	 }
					}
		        	 
            }
	        if(list.size()>0){
	        	Query rquery =null;
	        	if(startTime!=null && endTime!=null){
	        		rquery= Query.query(Criteria.where("analyse_date").is(startTime));
	        	}else{
	        		rquery= Query.query(Criteria.where("analyse_date").is(analyseDate));
	        	}
	        	int count = egovMongoTemplate.remove(rquery, "tourist_vehicle_area_inout").getN();
	        	if(count>0){
	        		logger.info("删除已经分析过的旅游车辆异常数据"+count+"条");
	        	}
		        egovMongoTemplate.insert(list, "tourist_vehicle_area_inout");
		        logger.info("入库"+list.size()+"到tourist_vehicle_area_inout中");
	        }
	        egovMongoTemplate.dropCollection(o_name);//用完后删除
        }
   
	}
	/**
	 * 旅游车异动 入库分析
	 * @param dirUrl
	 * @param analyseDate
	 * @param table_date
	 * @param vMap
	 */
	private void touristAnalyse(String dirUrl,Date analyseDate,String table_date,HashMap<Integer,Vehicle> vMap){
		Map<String,String> map = XmlReader.readXmlToMapReduce(dirUrl+"vehicle_swap_tourist.xml");
        if(map!=null&& map.size()>0){
        	DBObject command = new BasicDBObject();
       	DBObject sort = new BasicDBObject();
       	sort.put("_id",1);
    	DBCollection  db = egovMongoTemplate.getDb().getCollection("gps_info_"+table_date);
	    	 MapReduceCommand cmd = new MapReduceCommand(db,
	         map.get("map"), map.get("reduce"), "vehicle_swap_tourist_"+System.currentTimeMillis(), MapReduceCommand.OutputType.REPLACE, null);
	         cmd.setFinalize(map.get("finalize"));  
	         cmd.setSort(sort);
	         MapReduceOutput out = db.mapReduce(cmd);  
	         DBCollection resultColl = out.getOutputCollection();
	         String o_name = resultColl.getName();
	         DBCursor cursor= resultColl.find();
	         List list =new ArrayList();
	         if (cursor!=null) {  
	        	     List<DBObject> lob = cursor.toArray();
	        	     for (DBObject ob : lob) {
			        	 DBObject _id = (DBObject) ob.get("_id"); 
			        	 DBObject value = (DBObject) ob.get("value"); 
		                 List<Date> dateList = (List<Date>) value.get("gps_time");
		            	 int vid = Integer.parseInt(String.valueOf(_id.get("vehicle_id")));
		            	 Vehicle veh = vMap.get(vid);
		                 if(dateList!=null && dateList.size()>0 && veh!=null){
		                     List<DBObject> pointList =   (List<DBObject>) value.get("coordinates");
		                     list.addAll(getListOBJ(dateList, pointList, veh, analyseDate/*, table_date*/)); 
		                 }
					}
		        	 
            }
	        if(list.size()>0){
		    	Query rquery = Query.query(Criteria.where("analyse_date").is(analyseDate));
	        	int count = egovMongoTemplate.remove(rquery, "tourist_vehicle_exception").getN();
	        	if(count>0){
	        		logger.info("删除已经分析过的旅游车辆异常数据"+count+"条");
	        	}
		        egovMongoTemplate.insert(list, "tourist_vehicle_exception");
		        logger.info("入库"+list.size()+"到tourist_vehicle_exception中");
	        }
	        egovMongoTemplate.dropCollection(o_name);//用完后删除
        }
   
	}
	/**
	 * 旅游车异动——业户维度
	 */
	private void touristEnterpriseAnalyse(String dirUrl,Date analyseDate,String table_date){
		Map<String,String> map = XmlReader.readXmlToMapReduce(dirUrl+"tourist_vehicle_exception_enterprise.xml");
        if(map!=null&& map.size()>0){
        	DBObject command = new BasicDBObject();
       	DBObject sort = new BasicDBObject();
       	sort.put("_id",1);
    	DBCollection  db = egovMongoTemplate.getDb().getCollection("tourist_vehicle_exception");
	    	 MapReduceCommand cmd = new MapReduceCommand(db,
	         map.get("map"), map.get("reduce"), "vehicle_swap_tourist_enterprise_"+System.currentTimeMillis(), MapReduceCommand.OutputType.REPLACE, null);
	         cmd.setFinalize(map.get("finalize"));  
	         cmd.setSort(sort);
	         MapReduceOutput out = db.mapReduce(cmd);  
	         DBCollection resultColl = out.getOutputCollection();
	         String o_name = resultColl.getName();
	         DBCursor cursor= resultColl.find();
	         List list =new ArrayList();
	         if (cursor!=null) {  
	        	     List<DBObject> lob = cursor.toArray();
	        	     for (DBObject ob : lob) {
			        	 DBObject _id = (DBObject) ob.get("_id"); 
			        	 DBObject value = (DBObject) ob.get("value"); 
		                 int eid = Integer.parseInt(String.valueOf(_id.get("enterprise_id")));
		                 value.put("_id", table_date+":"+eid);
		                 value.put("enterprise_id",eid);
		                 value.put("analyse_date", analyseDate);
		                 list.add(value);
					} 
            }
	        if(list.size()>0){
		    	Query rquery = Query.query(Criteria.where("analyse_date").is(analyseDate));
	        	int count = egovMongoTemplate.remove(rquery, "tourist_vehicle_exception_enterprise").getN();
	        	if(count>0){
	        		logger.info("删除已经分析过的旅游车异动——业户维度数据"+count+"条");
	        	}
		        egovMongoTemplate.insert(list, "tourist_vehicle_exception_enterprise");
		        logger.info("入库"+list.size()+"到tourist_vehicle_exception_enterprise中");
	        }
	        egovMongoTemplate.dropCollection(o_name);//用完后删除
        }
   
	}
	/**
	 * 获取对象
	 * @param dateList
	 * @param pointList
	 * @param veh
	 * @param analyseDate
	 * @param table_date
	 * @return
	 */
	private List<DBObject> getListOBJ(List<Date> dateList,List<DBObject> pointList,Vehicle veh,Date analyseDate/*,String table_date*/){
		List  list = new ArrayList();
		for (int i=0;i<dateList.size();i++) {
			DBObject obj = new BasicDBObject();
			obj.put("_id", DateUtils.format(dateList.get(i),Constants.DATE_YYMMDDHHMMSS)+":"+veh.getVehicle_no()+":"+veh.getVehicle_color());
			obj.put("vehicle_no", veh.getVehicle_no());
			obj.put("vehicle_color", veh.getVehicle_color());
			obj.put("enterprise_id", veh.getEnterprise_id());
			obj.put("enterprise_name", veh.getEnterprise_name());
			obj.put("analyse_date", analyseDate);
			obj.put("gps_time", dateList.get(i));
			obj.put("coordinates", pointList.get(i));
			list.add(obj);
		}
		return list;
	}
	
	/*
	 * 所有车
	 */
	public List getVehicleInfo(){
		return (List) this.select("getVehicleInfo", null);
	}
}
